const url = require('url'),
    qs = require('querystring'),
    crypto = require('crypto'),
    request = require('request'),
    xml2jsparseString = require('xml2js').parseString,
    getWebAuthAccessToken = require('../common/getWebAuthAccessToken'),
    wechatPay = require('../config/config').wechatPay,
    wechatApi = require('../config/config').wechatApi;


let unifiedOrderParams = {
        appid : wechatPay.appId,
        attach : 'ATTACH',
        body : 'BODY',
        mch_id : wechatPay.mchId,
        nonce_str: createNonceStr(),
        notify_url : wechatPay.afterPayUrl,// 微信付款后的回调地址
        openid : '',
        out_trade_no : new Date().getTime() ,//new Date().getTime(), //订单号
        spbill_create_ip : '' , //客户端的 ip
        total_fee : 1, //商品的价格， 此处需要注意的是这个价格是以分算的， 那么一般是元， 你需要转换为 RMB 的元
        trade_type : 'JSAPI'
    },

    brandWCPayParams = {
        "appId" : wechatPay.appId,
        "timeStamp" : parseInt(new Date().getTime() / 1000).toString(),
        "nonceStr" : createNonceStr(),
        // 通过统一下单接口获取
        "package" : "",
        "signType" : "MD5",         //微信签名方式：
    };


/**
 * @author: ares
 * @date: 2018/4/9 17:35
 * @description: 构建XML格式的微信统一下单参数
 * @param {object} order  订单数据
 * @returns {string}
 */
function getUnifiedOrderXmlParams(order){
    let body = `<xml>
                    <appid>${order.appId}</appid>
                    <attach>${order.attach}</attach>
                    <body>${order.body}</body>
                    <mch_id>${order.mchId}</mch_id>
                    <nonce_str>${order.nonce_str}</nonce_str>
                    <notify_url>${order.notify_url}</notify_url>
                    <openid>${order.openid}</openid>
                    <out_trade_no>${order.out_trade_no}</out_trade_no>
                    <spbill_create_ip>${order.spbill_create_ip}</spbill_create_ip>
                    <total_fee>${order.total_fee}</total_fee>
                    <trade_type>${order.trade_type}</trade_type>
                    <sign>${order.sign}</sign>
                </xml>`;
    return body;
}

/**
 * @author: ares
 * @date: 2018/4/10 9:35
 * @description: 获取微信统一下单的预付id prepay_id
 * @returns {Promise}
 */
function getPrepayId(){
    // 返回 promise 对象
    return  new Promise(function (resolve, reject) {
        // 获取 sign 参数
        unifiedOrderParams.sign = getSign(unifiedOrderParams);
        let option = {
            method:'post',
            url: wechatPay.packageApi,
            body: getUnifiedOrderXmlParams(unifiedOrderParams)
        };
        request(option, function (error, response, body) {
            let prepay_id = '';
            if (!error && response.statusCode == 200) {
                // 微信返回的数据为 xml 格式， 需要装换为 json 数据， 便于使用
                xml2jsparseString(body, {async:true}, function (error, result) {
                    prepay_id = result.xml.prepay_id[0];
                    // 放回数组的第一个元素
                    resolve(prepay_id);
                });
            } else {
                reject(body);
            }
        });
    })
}

/**
 * @author: ares
 * @date: 2018/4/9 17:39
 * @description: 计算微信签名
 * @param {object} sign_params  签名参数
 * @returns {string}
 */
function getSign(sign_params){
    // 按 key 值的ascll 排序
    let keys = Object.keys(sign_params),
        temp_args = {};
    keys = keys.sort();
    keys.forEach(function (val, key) {
        if (sign_params[val]){
            temp_args[val] = sign_params[val];
        }
    })
    let string = qs.stringify(temp_args) + '&key=' + wechatPay.apiKey;
    // 生成签名
    return crypto.createHash('md5').update(qs.unescape(string), 'utf8').digest("hex").toUpperCase();
}

/**
 * @author: ares
 * @date: 2018/4/10 9:32
 * @description: 构建客户端发起支付请求所需参数
 * @param {object} req
 */
function buildBrandWCPayParams(req ){
    getWebAuthAccessToken(req.query.code).then(data => {
        let res = JSON.parse(data);
        unifiedOrderParams.openid = res.openid;
        unifiedOrderParams.spbill_create_ip = req.ip;
        getPrepayId().then(prepayId => {
            brandWCPayParams.package = "prepay_id=" + prepayId;
            brandWCPayParams.paySign = getSign(brandWCPayParams); //微信支付签名
            return brandWCPayParams;
        }).catch (error => {
            console.log(error);
        });
    })
}

/**
 * @author: ares
 * @date: 2018/4/9 16:50
 * @description: 生成随机的NonceStr
 */
function createNonceStr() {
    return Math.random().toString(36).substr(2, 15);
}


module.exports = buildBrandWCPayParams;